package com.tomato.base.dynamic.db.spring.boot.autoconfigure;

import com.alibaba.druid.pool.DruidDataSource;
import com.tomato.base.dynamic.db.enums.StrategyTypeEnum;
import com.tomato.base.dynamic.db.router.DynamicDataSourceAspect;
import com.tomato.base.dynamic.db.router.DynamicTableAspect;
import com.tomato.base.dynamic.db.spring.boot.autoconfigure.properties.DynamicDataSourceContextProperties;
import com.tomato.base.dynamic.db.spring.boot.autoconfigure.properties.DynamicDataSourceProperties;
import com.tomato.base.dynamic.db.interceptor.DynamicMybatisInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 数据源配置解析
 *
 * @author lizhifu
 * @date 2022/3/9
 */
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
@AutoConfigureBefore(name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure")
public class DynamicDataSourceAutoConfig {
    private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAutoConfig.class);
    @Resource
    private DynamicDataSourceProperties dynamicDataSourceProperties;
    /**
     * mybatis 拦截器
     * @return
     */
    @Bean
    public Interceptor plugin() {
        return new DynamicMybatisInterceptor();
    }
    /**
     * aop
     * @return
     */
    @Bean
    public DynamicDataSourceAspect dynamicDataSourceAspectAutoConfig() {
        return new DynamicDataSourceAspect(dynamicDataSourceProperties);
    }
    @Bean
    public DynamicTableAspect dynamicTableAspect() {
        return new DynamicTableAspect(dynamicDataSourceProperties);
    }
    @Bean
    public DataSource dataSource() {
        // 创建数据源
        Map<Object, Object> targetDataSources = new HashMap<>();
        for (String key : dynamicDataSourceProperties.getDynamic().keySet()) {
            DynamicDataSourceContextProperties dbInfo = dynamicDataSourceProperties.getDynamic().get(key);
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setUrl(dbInfo.getUrl());
            druidDataSource.setUsername(dbInfo.getUsername());
            druidDataSource.setPassword(dbInfo.getPassword());
            druidDataSource.setDriverClassName(dbInfo.getDriverClassName());

            targetDataSources.put(key, druidDataSource);
            logger.info("动态数据源加载 key is {}",key);
        }
        // 设置数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(targetDataSources.get(dynamicDataSourceProperties.getPrimary()));
        return dynamicDataSource;
    }

    @Bean
    public TransactionTemplate transactionTemplate(DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);

        TransactionTemplate transactionTemplate = new TransactionTemplate();
        transactionTemplate.setTransactionManager(dataSourceTransactionManager);
        // 表示当前方法必须运行在事务中，若当前存在事务，则在原有事务中运行，否则创建一个新的事务。
        transactionTemplate.setPropagationBehaviorName("PROPAGATION_REQUIRED");
        return transactionTemplate;
    }
}
